package cjj.jvm;

/**
 * @author junjie.chen
 * @email junjie.chen@dmall.com
 * @date 2018/11/9
 */
public class StaticTest {
    public static void main(String[] args)
    {
        staticFunction();
    }

    static StaticTest st = new StaticTest();

   final static String h = "hello";

    static
    {
        System.out.println("1");
    }

    {
        System.out.println("2");
    }

    StaticTest()
    {
        System.out.println("3");
        System.out.println("a="+a+",b="+b);
    }

    public static void staticFunction(){
        System.out.println("4");
    }

    int a=110;
    static int b =112;
}



/**
 * 反编译文件   static StaticTest st = new StaticTest();
 * 运行结果：
 *      2
 *      3
 *      a=110,b=0
 *      1
 *      4
 *
 * 反编译内容：
 * D:\gitee\java\my_java_test\target\classes\cjj\jvm>javap -v StaticTest.class
 * Classfile /D:/gitee/java/my_java_test/target/classes/cjj/jvm/StaticTest.class
 *   Last modified 2018-11-9; size 1074 bytes
 *   MD5 checksum 567a593923c4dad6aabe7438384842b7
 *   Compiled from "StaticTest.java"
 * public class cjj.jvm.StaticTest
 *   minor version: 0
 *   major version: 52
 *   flags: ACC_PUBLIC, ACC_SUPER
 * Constant pool:
 *    #1 = Methodref          #17.#41        // cjj/jvm/StaticTest.staticFunction:()V
 *    #2 = Methodref          #21.#42        // java/lang/Object."<init>":()V
 *    #3 = Fieldref           #43.#44        // java/lang/System.out:Ljava/io/PrintStream;
 *    #4 = String             #45            // 2
 *    #5 = Methodref          #46.#47        // java/io/PrintStream.println:(Ljava/lang/String;)V
 *    #6 = Fieldref           #17.#48        // cjj/jvm/StaticTest.a:I
 *    #7 = String             #49            // 3
 *    #8 = Class              #50            // java/lang/StringBuilder
 *    #9 = Methodref          #8.#42         // java/lang/StringBuilder."<init>":()V
 *   #10 = String             #51            // a=
 *   #11 = Methodref          #8.#52         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 *   #12 = Methodref          #8.#53         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
 *   #13 = String             #54            // ,b=
 *   #14 = Fieldref           #17.#55        // cjj/jvm/StaticTest.b:I
 *   #15 = Methodref          #8.#56         // java/lang/StringBuilder.toString:()Ljava/lang/String;
 *   #16 = String             #57            // 4
 *   #17 = Class              #58            // cjj/jvm/StaticTest
 *   #18 = Methodref          #17.#42        // cjj/jvm/StaticTest."<init>":()V
 *   #19 = Fieldref           #17.#59        // cjj/jvm/StaticTest.st:Lcjj/jvm/StaticTest;
 *   #20 = String             #60            // 1
 *   #21 = Class              #61            // java/lang/Object
 *   #22 = Utf8               st
 *   #23 = Utf8               Lcjj/jvm/StaticTest;
 *   #24 = Utf8               a
 *   #25 = Utf8               I
 *   #26 = Utf8               b
 *   #27 = Utf8               main
 *   #28 = Utf8               ([Ljava/lang/String;)V
 *   #29 = Utf8               Code
 *   #30 = Utf8               LineNumberTable
 *   #31 = Utf8               LocalVariableTable
 *   #32 = Utf8               args
 *   #33 = Utf8               [Ljava/lang/String;
 *   #34 = Utf8               <init>
 *   #35 = Utf8               ()V
 *   #36 = Utf8               this
 *   #37 = Utf8               staticFunction
 *   #38 = Utf8               <clinit>
 *   #39 = Utf8               SourceFile
 *   #40 = Utf8               StaticTest.java
 *   #41 = NameAndType        #37:#35        // staticFunction:()V
 *   #42 = NameAndType        #34:#35        // "<init>":()V
 *   #43 = Class              #62            // java/lang/System
 *   #44 = NameAndType        #63:#64        // out:Ljava/io/PrintStream;
 *   #45 = Utf8               2
 *   #46 = Class              #65            // java/io/PrintStream
 *   #47 = NameAndType        #66:#67        // println:(Ljava/lang/String;)V
 *   #48 = NameAndType        #24:#25        // a:I
 *   #49 = Utf8               3
 *   #50 = Utf8               java/lang/StringBuilder
 *   #51 = Utf8               a=
 *   #52 = NameAndType        #68:#69        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 *   #53 = NameAndType        #68:#70        // append:(I)Ljava/lang/StringBuilder;
 *   #54 = Utf8               ,b=
 *   #55 = NameAndType        #26:#25        // b:I
 *   #56 = NameAndType        #71:#72        // toString:()Ljava/lang/String;
 *   #57 = Utf8               4
 *   #58 = Utf8               cjj/jvm/StaticTest
 *   #59 = NameAndType        #22:#23        // st:Lcjj/jvm/StaticTest;
 *   #60 = Utf8               1
 *   #61 = Utf8               java/lang/Object
 *   #62 = Utf8               java/lang/System
 *   #63 = Utf8               out
 *   #64 = Utf8               Ljava/io/PrintStream;
 *   #65 = Utf8               java/io/PrintStream
 *   #66 = Utf8               println
 *   #67 = Utf8               (Ljava/lang/String;)V
 *   #68 = Utf8               append
 *   #69 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
 *   #70 = Utf8               (I)Ljava/lang/StringBuilder;
 *   #71 = Utf8               toString
 *   #72 = Utf8               ()Ljava/lang/String;
 * {
 *   static cjj.jvm.StaticTest st;
 *     descriptor: Lcjj/jvm/StaticTest;
 *     flags: ACC_STATIC
 *
 *   int a;
 *     descriptor: I
 *     flags:
 *
 *   static int b;
 *     descriptor: I
 *     flags: ACC_STATIC
 *
 *   public static void main(java.lang.String[]);
 *     descriptor: ([Ljava/lang/String;)V
 *     flags: ACC_PUBLIC, ACC_STATIC
 *     Code:
 *       stack=0, locals=1, args_size=1
 *          0: invokestatic  #1                  // Method staticFunction:()V
 *          3: return
 *       LineNumberTable:
 *         line 11: 0
 *         line 12: 3
 *       LocalVariableTable:
 *         Start  Length  Slot  Name   Signature
 *             0       4     0  args   [Ljava/lang/String;
 *
 *   cjj.jvm.StaticTest();
 *     descriptor: ()V
 *     flags:
 *     Code:
 *       stack=3, locals=1, args_size=1
 *          0: aload_0
 *          1: invokespecial #2                  // Method java/lang/Object."<init>":()V
 *          4: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *          7: ldc           #4                  // String 2
 *          9: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         12: aload_0
 *         13: bipush        110
 *         15: putfield      #6                  // Field a:I
 *         18: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         21: ldc           #7                  // String 3
 *         23: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         26: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         29: new           #8                  // class java/lang/StringBuilder
 *         32: dup
 *         33: invokespecial #9                  // Method java/lang/StringBuilder."<init>":()V
 *         36: ldc           #10                 // String a=
 *         38: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 *         41: aload_0
 *         42: getfield      #6                  // Field a:I
 *         45: invokevirtual #12                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
 *         48: ldc           #13                 // String ,b=
 *         50: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 *         53: getstatic     #14                 // Field b:I
 *         56: invokevirtual #12                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
 *         59: invokevirtual #15                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
 *         62: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         65: return
 *       LineNumberTable:
 *         line 26: 0
 *         line 22: 4
 *         line 35: 12
 *         line 27: 18
 *         line 28: 26
 *         line 29: 65
 *       LocalVariableTable:
 *         Start  Length  Slot  Name   Signature
 *             0      66     0  this   Lcjj/jvm/StaticTest;
 *
 *   public static void staticFunction();
 *     descriptor: ()V
 *     flags: ACC_PUBLIC, ACC_STATIC
 *     Code:
 *       stack=2, locals=0, args_size=0
 *          0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *          3: ldc           #16                 // String 4
 *          5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *          8: return
 *       LineNumberTable:
 *         line 32: 0
 *         line 33: 8
 *
 *   static {};
 *     descriptor: ()V
 *     flags: ACC_STATIC
 *     Code:
 *       stack=2, locals=0, args_size=0
 *          0: new           #17                 // class cjj/jvm/StaticTest
 *          3: dup
 *          4: invokespecial #18                 // Method "<init>":()V
 *          7: putstatic     #19                 // Field st:Lcjj/jvm/StaticTest;
 *         10: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         13: ldc           #20                 // String 1
 *         15: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         18: bipush        112
 *         20: putstatic     #14                 // Field b:I
 *         23: return
 *       LineNumberTable:
 *         line 14: 0
 *         line 18: 10
 *         line 36: 18
 * }
 * SourceFile: "StaticTest.java"
 *
 *
 * */



/**
 * 反编译文件   StaticTest st = new StaticTest();
 * 运行结果：
 *      1
 *      4
 *
 * 反编译内容：
 * D:\gitee\java\my_java_test\target\classes\cjj\jvm>javap -c StaticTest.class
 * Compiled from "StaticTest.java"
 * public class cjj.jvm.StaticTest {
 *         cjj.jvm.StaticTest st;
 *
 *         int a;
 *
 * static int b;
 *
 * public static void main(java.lang.String[]);
 *         Code:
 *         0: invokestatic  #1                  // Method staticFunction:()V
 *         3: return
 *
 *         cjj.jvm.StaticTest();
 *         Code:
 *         0: aload_0
 *         1: invokespecial #2                  // Method java/lang/Object."<init>":()V
 *         4: aload_0
 *         5: new           #3                  // class cjj/jvm/StaticTest
 *         8: dup
 *         9: invokespecial #4                  // Method "<init>":()V
 *         12: putfield      #5                  // Field st:Lcjj/jvm/StaticTest;
 *         15: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         18: ldc           #7                  // String 2
 *         20: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         23: aload_0
 *         24: bipush        110
 *         26: putfield      #9                  // Field a:I
 *         29: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         32: ldc           #10                 // String 3
 *         34: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         37: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         40: new           #11                 // class java/lang/StringBuilder
 *         43: dup
 *         44: invokespecial #12                 // Method java/lang/StringBuilder."<init>":()V
 *         47: ldc           #13                 // String a=
 *         49: invokevirtual #14                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 *         52: aload_0
 *         53: getfield      #9                  // Field a:I
 *         56: invokevirtual #15                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
 *         59: ldc           #16                 // String ,b=
 *         61: invokevirtual #14                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 *         64: getstatic     #17                 // Field b:I
 *         67: invokevirtual #15                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
 *         70: invokevirtual #18                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
 *         73: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         76: return
 *
 * public static void staticFunction();
 *         Code:
 *         0: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         3: ldc           #19                 // String 4
 *         5: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         8: return
 *
 * static {};
 *         Code:
 *         0: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         3: ldc           #20                 // String 1
 *         5: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         8: bipush        112
 *         10: putstatic     #17                 // Field b:I
 *         13: return
 * }

*
**/

/**
 * 总结：
 *
 * 可以看出他们的区别在于 “static {}” 这里
 *
 * 对于StaticTest st = new StaticTest()而言，static {} 执行的内容如下：
 * static {};
 *         Code:
 *         0: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         3: ldc           #20                 // String 1
 *         5: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         8: bipush        112
 *         10: putstatic     #17                 // Field b:I
 *         13: return
 *
 *
 * 对于static StaticTest st = new StaticTest()而言，static {} 执行的内容如下：
 *    static {};
 *         Code:
 *         0: new           #17                 // class cjj/jvm/StaticTest
 *         3: dup
 *         4: invokespecial #18                 // Method "<init>":()V
 *         7: putstatic     #19                 // Field st:Lcjj/jvm/StaticTest;
 *         10: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
 *         13: ldc           #20                 // String 1
 *         15: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 *         18: bipush        112
 *         20: putstatic     #14                 // Field b:I
 *         23: return
 *
 *
 *
 */